home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Telnet
/
NCSA
/
tn3270 2.3d26 source
/
tn3270
/
scrap.c
< prev
next >
Wrap
Text File
|
1991-01-21
|
16KB
|
713 lines
/*
* tn3270 for the Macintosh Source Code
* Brown University Computing and Information Services
* Version 2.3d21, January 17, 1991
* Copyright (c) 1988, 1989, 1990, 1991 by Brown University and by
* Peter John DiCamillo.
*
* Permission is granted to any individual or institution to use, copy,
* or redistribute the binary version of this software and its
* documentation provided this notice and the copyright notices are
* retained. Permission is granted to any individual or non-profit
* institution to use, copy, modify, or redistribute the source files
* of this software provided this notice and the copyright notices are
* retained. This software may not be distributed for profit, either
* in original form or in derivative works, nor can the source be
* distributed to other than an individual or a non-profit institution.
* Any individual or group interested in seeing and/or using these
* source files but who are prevented from doing so by the above
* constraints should contact Don Wolfe, Assistant Vice-President for
* Computer Systems at Brown University, (401) 863-7250, for possible
* software licensing of the source developed at Brown.
*
* Brown University and Peter John DiCamillo make no representations
* about the suitability of this software for any purpose.
*
* BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
* EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
* INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#define __SEG__ 3270seg2
#include <Scrap.h>
#include "maclib.h"
#include "termdef.h"
#include "globals.h"
extern short maxcnt, maxoff, scrhsize, scrhoff;
extern Handle alaxtabh;
static char tableflag = 0;
static char textflag = 0;
static char calcflag;
static long calcsize;
static unsigned char * scrapptr;
static unsigned char * expresult;
static unsigned short * expresattr;
unsigned char cutflag = 0;
OSErr newscrap()
{
long allocsize;
scrapline * sp;
unsigned char * chrptr;
short i;
/* Return if there is already a scrap of the proper width */
if ((scrapstart != 0) && (scrapwidth == ses_altcols)) {
return(noErr);
}
/* Remove an existing scrap */
if (scrapstart != 0) {
removescrap();
}
/* Allocate new scrap */
scrapalloc = ses_altrows; /* permanent allocation is one screen */
scrapwidth = ses_altcols; /* width always matches widest possible */
allocsize = sizeof(struct scrapline) * scrapalloc;
allocsize += scrapalloc * scrapwidth * 3; /* 1 byte for char, 2 for attrs. */
allocsize += scrapwidth * 3; /* for expresult and expresattr */
scrapstart = (scrapline *)myNewPtr(allocsize);
if (scrapstart == 0L) {
return(1);
}
chrptr = (unsigned char *)scrapstart;
chrptr += sizeof(struct scrapline) * scrapalloc;
sp = scrapstart;
for (i=0; i < scrapalloc-1; i++) {
sp->nextline = sp + 1;
sp->text = chrptr;
chrptr += scrapwidth;
sp->attr = (unsigned short *)chrptr;
chrptr += scrapwidth * 2;
sp++;
}
sp->nextline = 0;
sp->text = chrptr;
chrptr += scrapwidth;
sp->attr = (unsigned short *)chrptr;
chrptr += scrapwidth * 2;
expresult = chrptr;
chrptr += scrapwidth;
expresattr = (unsigned short *)chrptr;
scrapsize = 0; /* no lines in use */
return(0);
}
removescrap()
{
scrapline *sp, *nextsp;
if (scrapstart == 0) {
return;
}
exportscrap(1); /* copy private scrap to desk scrap */
/* return private scrap storage */
sp = scrapstart;
sp += scrapalloc - 1; /* sp -> last permanent element */
nextsp = sp->nextline; /* nextsp -> first extra element, if any */
while (nextsp != 0) { /* free each extra element */
sp = nextsp;
nextsp = sp->nextline;
DisposPtr(sp);
}
DisposPtr(scrapstart); /* free permanent elements */
scrapstart = 0;
}
importscrap()
{
scrapsize = 0; /* temp */
}
exportscrap(endflag)
char endflag;
{
unsigned char * scrapmem;
OSErr rc;
if (scrapsize == 0) return; /* nothing to do if no scrap */
/* calculate size of exported scrap */
calcsize = 0;
calcflag = 1;
doexport();
/* return if size = 0 */
if (calcsize == 0) return;
/* allocate memory to hold scrap */
scrapmem = (unsigned char *)myNewPtr(calcsize);
if (scrapmem == 0) {
beep();
return;
}
/* initialize scrap */
rc = ZeroScrap();
if (rc != 0) {
DisposPtr(scrapmem);
beep();
return;
}
/* copy data to scrap and return storage */
scrapptr = scrapmem;
calcflag = 0;
doexport();
rc = PutScrap(calcsize, 'TEXT', scrapmem);
DisposPtr(scrapmem);
if (rc != 0) {
beep();
return;
}
/* if end call, load scrap into memory */
if (endflag) LoadScrap();
}
doexport()
{
register short col;
short startoff, len, colstart, colend;
short linecount;
char expstate, initsel, sel, anytext;
scrapline * sp;
scrapline currline;
sp = scrapstart;
linecount = 0;
anytext = 0;
while (linecount < scrapsize) {
currline = *sp; /* make local copy of current line */
/* find first selected printable character */
colstart = 0;
initsel = 0;
while (colstart < scrapwidth) {
if ((currline.attr)[colstart] & 0x0020) {
if (((currline.text)[colstart] != 0) &&
((currline.text)[colstart] != 0x40) &&
(((currline.attr)[colstart] & 0x8000) == 0)) {
if ((initsel == 0) && textflag && anytext) expbreak();
anytext = initsel = 1;
break;
}
else {
if ((initsel == 0) && textflag) {
expendline();
anytext = 0;
}
initsel = 1;
}
}
colstart++;
}
/* if no printable characters, output null line */
if (colstart == scrapwidth) {
if (initsel) {
expendline();
anytext = 0;
}
linecount++;
sp = sp->nextline;
continue;
}
/* find last printable character */
colend = scrapwidth - 1;
while (colend >= 0) {
if (((currline.attr)[colend] & 0x0020) &&
((currline.text)[colend] != 0) &&
((currline.text)[colend] != 0x40) &&
(((currline.attr)[colend] & 0x8000) == 0)) break;
else colend--;
}
expstate = 0;
initsel = 0;
for (col = colstart; col <= colend; col++) {
sel = ((currline.attr)[col] & 0x0020) != 0;
if (tableflag || (!initsel)) {
sel = sel && ((currline.text)[col] != 0)
&& ((currline.text)[col] != 0x40)
&& (((currline.attr)[col] & 0x8000) == 0);
initsel = sel;
}
switch(expstate) {
case 0: /* before first field */
if (sel) {
startoff = col;
len = 1;
expstate = 1;
}
break;
case 1: /* within field */
if (sel) {
len++;
}
else {
expfield(&currline, startoff, len);
startoff = col;
len = 1;
expstate = 2;
initsel = 0;
}
break;
case 2: /* between fields */
if (sel) {
expbreak(&currline, startoff, len);
startoff = col;
len = 1;
expstate = 1;
}
else {
len++;
}
break;
default:
break;
}
}
switch(expstate) { /* end-of-line processing */
case 0: /* before first field */
break;
case 1: /* within field */
expfield(&currline, startoff, len);
if (!textflag) expendline();
break;
case 2: /* between fields */
if (!textflag) expendline();
break;
default:
break;
}
linecount++;
sp = sp->nextline;
}
}
expfield(sp, offset, len)
scrapline * sp;
register short offset, len;
{
short linelen;
register short i;
char alaflag, dcflag;
unsigned char alatrans();
scrapline currline;
currline = *sp; /* make copy of current line */
/* adjust offset and length to eliminate leading blanks, nulls, and
attributes (shouldn't happen). */
while (len > 0) {
if (((currline.text)[offset] == 0x00) ||
((currline.text)[offset] == 0x40) ||
((currline.attr)[offset] & 0x8000)) {
offset++;
len--;
}
else break;
}
/* adjust length to eliminate trailing blanks, nulls, and attributes */
while (len > 0) {
if (((currline.text)[offset+len-1] == 0x00) ||
((currline.text)[offset+len-1] == 0x40) ||
((currline.attr)[offset+len-1] & 0x8000)) {
len--;
}
else break;
}
/* skip field if no printable characters (shouldn't happen) */
if (len == 0) return;
/* copy field to buffer, handling nulls, and replacing attribute
bytes by blanks */
linelen = 0;
dcflag = 0;
alaflag = (stdfont == ALAFONT);
for (i=0; i < len; i++) {
if ((currline.attr)[offset+i] & 0x8000) {
expresult[linelen] = 0x40;
expresattr[linelen++] = (currline.attr)[offset+i];
if (alaflag) {
expresattr[linelen] &= 0xff00;
dcflag = 0;
}
}
else if ((currline.text)[offset+i] == 0x00) {
if (cs.repnull) {
expresult[linelen] = 0x40;
expresattr[linelen++] - (currline.attr)[offset+i];
if (alaflag) {
expresattr[linelen] &= 0xff00;
dcflag = 0;
}
}
}
else {
if (alaflag) {
if (alatype((currline.text)+offset+i) == 2) { /* is a diacritic */
expresult[linelen] = (currline.text)[offset+i];
expresattr[linelen++] = (currline.attr)[offset+i] & 0xff00;
dcflag = 1;
}
else { /* not a diacritic */
if (dcflag) {
if ((currline.text)[offset+i] != 0x40) {
expresattr[linelen-1] |= (currline.text)[offset+i];
}
dcflag = 0;
}
else {
expresult[linelen] = (currline.text)[offset+i];
expresattr[linelen++] = (currline.attr)[offset+i] & 0xff00;
}
}
}
else {
expresult[linelen] = (currline.text)[offset+i];
expresattr[linelen++] = (currline.attr)[offset+i];
}
}
}
/* translate from EBCDIC to Mac ASCII */
for (i=0; i < linelen; i++)
if (expresattr[i] & 0x4000) { /* APL character */
expresult[i] = (*xtabh)[expresult[i] + 256];
}
else {
if (nl_handle != 0) {
expresult[i] = (*xtabh)[nltab[expresult[i]]];
}
else {
if (alaflag) {
expresult[i] = alatrans(expresult[i], expresattr[i] & 0xff);
}
else {
expresult[i] = (*xtabh)[expresult[i]];
}
}
}
/* add to the desk scrap */
myPutScrap(linelen, expresult);
}
unsigned char alatrans(dc, chr)
unsigned char dc, chr;
{
unsigned char *chrlist, *dclist, *dcdata;
register short i;
short chrindex, dcindex;
unsigned char c;
if (chr == 0) return((*xtabh)[dc+512]); /* no diacritic */
chrlist = (*alaxtabh);
dclist = chrlist+16;
dcdata = chrlist+32;
/* get table index for character */
chrindex = -1;
for (i=0; i < 16; i++) {
if (chrlist[i] == 0) break;
if (chr == chrlist[i]) {
chrindex = i;
break;
}
}
if (chrindex < 0) return((*xtabh)[chr+512]);
/* get table index for diacritic */
dcindex = -1;
for (i=0; i < 16; i++) {
if (dclist[i] == 0) break;
if (dc == dclist[i]) {
dcindex = i;
break;
}
}
if (dcindex < 0) return((*xtabh)[chr+512]);
c = dcdata[(dcindex << 4) + chrindex];
if (c == 0) return((*xtabh)[chr+512]);
else return(c);
}
expbreak(offset, len)
short offset, len;
{
unsigned char breakchar[1];
if (tableflag) breakchar[0] = 0x09;
else breakchar[0] = 0x20;
myPutScrap(1, breakchar);
}
expendline()
{
static unsigned char endchar[1] = 0x0d;
myPutScrap(1, endchar);
}
myPutScrap(len, data)
short len; unsigned char * data;
{
if (calcflag) {
calcsize += len;
return;
}
memcpy(scrapptr, data, len);
scrapptr += len;
}
scrapcut(append)
char append;
{
register unsigned short i, offset, a, attroff;
char protfield, protflag;
tableflag = textflag = 0;
scopy(append);
if (!fmtscrn) {
cutflag = 1;
for (i=0; i < maxcnt; i++) {
if (atrbuff[i] & 0x0020) dselchar(i, 0);
}
cutflag = 0;
invldscr();
return;
}
offset=firstattr();
cutflag = 1;
protflag = 0;
for (i=0; i < maxcnt; i++) {
a = atrbuff[offset];
if (a & 0x8000) { /* handle attribute byte */
protfield = (a & 0x2000) != 0;
attroff = offset;
}
if (((a & 0x8020) == 0x0020) && (!protfield)) {
dselchar(offset, attroff);
}
else {
if (a & 0x0020) protflag = 1;
}
offset++;
if (offset > maxoff) offset = 0;
}
invldscr();
if (protflag) beep();
cutflag = 0;
}
scrapcopy(append)
char append;
{
tableflag = textflag = 0;
scopy(append);
}
scrappaste()
{
char message[80];
char dbsave;
sprintf(message, "Sorry, Paste isn't implemented yet");
arrowcursor();
dbsave = cs.dblevel;
cs.dblevel = 1;
dbdlg(message);
cs.dblevel = dbsave;
}
scrapclear()
{
selclear(0x00);
}
scrapcopytable(append)
char append;
{
tableflag = 1;
textflag = 0;
scopy(append);
}
scrapcopytext(append)
char append;
{
tableflag = 0;
textflag = 1;
scopy(append);
}
scopy(append)
char append;
{
register short rowoff, coloff;
short i;
char found, scrapinit, scrapappend;
scrapline * sp, *nextsp;
unsigned char *chrptr;
long allocsize;
scrapinit = scrapappend = 0;
for (rowoff = 0; rowoff < maxcnt; rowoff += scrhsize) {
found = 0;
for (coloff = 0; coloff < scrhsize; coloff++)
if (atrbuff[rowoff+coloff] & 0x0020) {
found = 1;
break;
}
if (!found) continue;
if (!scrapinit) { /* set sp before adding first line */
scrapinit = 1;
if (!append) scrapsize = 0;
sp = scrapstart;
if (scrapsize > 1)
for (i=0; i < scrapsize-1; i++) sp = sp->nextline;
}
/* add new line after last line */
if (scrapsize > 0) {
if (sp->nextline == 0) {
allocsize = sizeof(struct scrapline);
allocsize += scrapwidth * 3;
sp->nextline = (struct scrapline *)myNewPtr(allocsize);
if (sp->nextline == 0) {
beep();
return;
}
scrapappend = 1;
(sp->nextline)->nextline = 0;
chrptr = (unsigned char *)sp->nextline;
chrptr += sizeof(struct scrapline);
(sp->nextline)->text = chrptr;
chrptr += scrapwidth;
(sp->nextline)->attr = (unsigned short *)chrptr;
}
sp = sp->nextline;
}
setmem(sp->text, scrapwidth, 0);
movmem(chrbuff+rowoff, sp->text, scrhsize);
setmem(sp->attr, scrapwidth*2, 0);
movmem(atrbuff+rowoff, sp->attr, scrhsize*2);
scrapsize++;
}
/* return if we didn't do anything or appended new lines */
if ((!scrapinit) || scrapappend) return;
/* free lines previously appended we no longer need */
if (scrapsize < scrapalloc) {
sp = scrapstart;
sp += scrapalloc - 1; /* sp -> last permanent element */
}
nextsp = sp->nextline; /* nextsp -> first unneeded element, if any */
sp->nextline = 0; /* end chain at last element needed */
while (nextsp != 0) {
sp = nextsp;
nextsp = sp->nextline;
DisposPtr(sp);
}
}
dselchar(start, attroff) /* delete selected characters */
unsigned short start, attroff;
{
register unsigned short src, padcount;
unsigned short i, end, dest;
if (fmtscrn) {
i = atrbuff[attroff];
}
else i = 0;
/* calculate last position to possibly change */
if (cs.repnull && fmtscrn) {
if (start > 0) end = start - 1;
else end = maxoff;
}
else {
end = ((start / scrhsize) + 1) * scrhsize - 1; /* last loc. on line */
}
src = dest = start;
padcount = 0;
while (1) {
if (atrbuff[src] & 0x8000) {
break;
}
if (atrbuff[src] & 0x0020) {
padcount++;
}
else {
newchar(dest, chrbuff[src], atrbuff[src], i);
dest++;
if (dest == maxcnt) dest = 0;
}
if (src == end) break; /* exit if just did the last one */
src++;
if (src == maxcnt) src = 0;
}
while (padcount > 0) {
newchar(dest, 0x00, 0, i);
dest++;
if (dest == maxcnt) dest = 0;
padcount--;
}
newwrite(0);
if (fmtscrn) atrbuff[attroff] |= 0x0100; /* set MDT bit */
}
selclear(fillchar)
unsigned char fillchar;
{
unsigned char t;
register unsigned char prot;
register short a, attroff, chroff, i;
char changeflag;
if (kblock) {
beep();
return;
}
changeflag = 0;
if (fmtscrn) a = firstattr();
else a = 0;
for (i=0; i < maxcnt; i++) {
if (atrbuff[a] & 0x8000) { /* attribute */
prot = (atrbuff[a] & 0x2000) != 0;
attroff = a; /* save attribute offset */
}
else if (fmtscrn) { /* character, formatted screen */
if ((atrbuff[a] & 0x0020) && (!prot)) {
newchar(a, fillchar, 0, atrbuff[attroff]);
atrbuff[attroff] |= 0x0100; /* set MDT bit */
changeflag = 1;
}
}
else { /* character, unformatted screen */
if (atrbuff[a] & 0x0020) {
newchar(a, fillchar, 0, 0);
changeflag = 1;
}
}
a++;
if (a == maxcnt) a = 0;
}
if (changeflag) {
newwrite(0);
}
else {
beep();
kerr(1);
}
}